package cz.uhk.max.matrix;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Matrix {
	protected int rowsCount;
	protected int colsCount;
	protected List<Row> rows = new ArrayList<Row>();

	/**
	 * Method print values from all columns to standard output.
	 */
	public void print() {
		for (int i = 0; i < this.rowsCount; i++) {
			System.out.print("Row" + i + ": ");
			for (int j = 0; j < this.colsCount; j++) {
				System.out.print("Col" + j + ": " + getCol(i, j).getValue()
						+ ", ");
			}
			System.out.println("");
		}
	}

	/**
	 * Constructor create an instance of Matrix that have the same number or
	 * rows and columns and same values of columns as matrix in input parameter.
	 * 
	 * @param M
	 *            Matrix M.
	 */
	
	public Matrix(){
		
	}
	public Matrix(List<Row> inrows){
		this.rowsCount = inrows.size();
		this.colsCount = inrows.get(0).getColsCount();
		for (int i = 0; i < rowsCount; i++) {
			rows.add(i, new Row(i, colsCount));
		}
		
		for (int i = 0; i < this.rowsCount; i++) {
			for (int j = 0; j < this.colsCount; j++) {
				this.setCol(i, j, inrows.get(i).getCols().get(j).getValue());
			}
		}
	}
	
	public Matrix(Matrix M) {
		this.rowsCount = M.getRowsCount();
		this.colsCount = M.getColsCount();

		for (int i = 0; i < rowsCount; i++) {
			rows.add(i, new Row(i, colsCount));
		}

		for (int i = 0; i < this.rowsCount; i++) {
			for (int j = 0; j < this.colsCount; j++) {
				this.setCol(i, j, M.getCol(i, j).getValue());
			}
		}
	}

	/**
	 * Constructor create an instance of Matrix that have the defined numbers or
	 * rows and columns.
	 * 
	 * @param rowsCount
	 *            Number of rows in matrix.
	 * @param colsCount
	 *            Number of columns in matrix.
	 */
	public Matrix(Integer rowsCount, Integer colsCount) {
		this.rowsCount = rowsCount;
		this.colsCount = colsCount;

		for (int i = 0; i < rowsCount; i++) {
			rows.add(i, new Row(i, colsCount));
		}
	}

	/**
	 * Method set all values in matrix to zero.
	 */
	public void clear() {
		for (int i = 0; i < this.rowsCount; i++) {
			for (int j = 0; j < this.colsCount; j++) {
				setCol(i, j, Long.parseLong("0"));
			}
		}
	};

	/**
	 * Method set all values in matrix to random number with defined maximum
	 * value. The maximum value is never generated.
	 * 
	 * @param maxNumber
	 *            The maximum value as input do random function.
	 */
	public void randomNumberGenerator(int maxNumber) {
		Random cislo = new Random();
		for (int i = 0; i < this.rowsCount; i++) {
			for (int j = 0; j < this.colsCount; j++) {
				setCol(i, j, cislo.nextInt(maxNumber));
			}
		}
	};

	/**
	 * Method return object Col from selected row and column index in matrix.
	 * 
	 * @param i
	 *            Index of row.
	 * @param j
	 *            Index of column.
	 */
	public Col getCol(int i, int j) {
		return rows.get(i).getCols().get(j);
	}

	/**
	 * Method set defined value to selected row and column.
	 * 
	 * @param i
	 *            Index of row.
	 * @param j
	 *            Index of column.
	 * @param Value
	 *            to put to column.
	 */
	public void setCol(int i, int j, Integer value) {
		rows.get(i).getCols().get(j).setValue(value.longValue());
	}

	/**
	 * Method set defined value to selected row and column.
	 * 
	 * @param i
	 *            Index of row.
	 * @param j
	 *            Index of column.
	 * @param Value
	 *            to put to column.
	 */
	public void setCol(int i, int j, Long value) {
		rows.get(i).getCols().get(j).setValue(value);
	}

	/**
	 * Method set number of rows in matrix.
	 * 
	 * @param rowsCount
	 *            Number of rows.
	 */
	public void setRowsCount(int rowsCount) {
		this.rowsCount = rowsCount;
	}

	/**
	 * Method return number of rows in matrix.
	 */
	public int getRowsCount() {
		return rowsCount;
	}

	/**
	 * Method set number of columns in matrix.
	 * 
	 * @param rowsCount
	 *            Number of columns.
	 */
	public void setColsCount(int colsCount) {
		this.colsCount = colsCount;
	}

	/**
	 * Method return number of columns in matrix.
	 */
	public int getColsCount() {
		return colsCount;
	}

	/**
	 * Method return collection of rows in matrix.
	 */
	public void setRows(List<Row> rows) {
		this.rows = rows;
	}

	public List<Row> getRows() {
		return rows;
	}

}
